package com.jysz.certificate.persistence.model.workflow;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

import com.jysz.certificate.persistence.enums.WorkflowOperateType;
import com.jysz.certificate.persistence.enums.WorkflowState;
import com.jysz.certificate.persistence.enums.WorkflowType;
import com.jysz.certificate.persistence.model.system.User;
import com.jysz.webcore.ssh.entity.AbstractBaseEntity;

/**
 * 审核流程
 * @author xuxiaolong
 */
@Entity
@Table(name = "wf_workflow_")
@org.hibernate.annotations.Entity
public class Workflow extends AbstractBaseEntity<Long> {

	private static final long serialVersionUID = -7999217347412163481L;
	
	/** 发起人 */
	private User sponsor;
	
	/** 状态*/
	private WorkflowState state;
	
	/**  流程类型 */
	private WorkflowType type;
	
	
	/** 对象类型 */
	private Class objType;
	
	/** 审核对象 */
	private List<WorkflowObject> objects;
	
	/** 操作记录 */
	private List<WorkflowOperate> operates;
	
	/** 拆分流程 */
	private Workflow splitWorkflow;

	public Workflow(){};
	public Workflow(User sponsor, WorkflowState state, WorkflowType type, Class objType, Long[]ids ){
		this.sponsor=sponsor;
		this.state=state;
		this.type=type;
		this.objType=objType;
		this.objects=buildWfObjects(this, ids);
	}
	
	@ManyToOne(targetEntity=User.class,cascade=CascadeType.REFRESH)
	@JoinColumn(name="_sponsor", insertable=true, updatable=true)
	public User getSponsor() {
		return sponsor;
	}

	public void setSponsor(User sponsor) {
		this.sponsor = sponsor;
	}
	
	@Column(name = "_state", nullable = false,columnDefinition="int(11)")
	@Enumerated(EnumType.ORDINAL)
	public WorkflowState getState() {
		return state;
	}

	public void setState(WorkflowState state) {
		this.state = state;
	}

	@Column(name = "_wf_type", nullable = false,columnDefinition="int(11)")
	public WorkflowType getType() {
		return type;
	}

	public void setType(WorkflowType type) {
		this.type = type;
	}

	@Column(name = "_obj_type", nullable = false,columnDefinition="varchar(255)")
	public Class getObjType() {
		return objType;
	}

	public void setObjType(Class objType) {
		this.objType = objType;
	}

	@OneToMany(targetEntity = WorkflowObject.class, cascade = { CascadeType.ALL }, mappedBy = "workflow")  
	@Fetch(FetchMode.SUBSELECT)
	public List<WorkflowObject> getObjects() {
		return objects;
	}

	public void setObjects(List<WorkflowObject> objects) {
		this.objects = objects;
	}

	@ManyToOne(fetch = FetchType.LAZY,cascade=CascadeType.ALL)  
	@JoinColumn(name = "_split",columnDefinition="bigint(20)")
	public Workflow getSplitWorkflow() {
		return splitWorkflow;
	}

	public void setSplitWorkflow(Workflow splitWorkflow) {
		this.splitWorkflow = splitWorkflow;
	}

	@OneToMany(targetEntity = WorkflowOperate.class, cascade = { CascadeType.ALL }, mappedBy = "workflow")  
	@Fetch(FetchMode.SUBSELECT)
	public List<WorkflowOperate> getOperates() {
		return operates;
	}

	public void setOperates(List<WorkflowOperate> operates) {
		this.operates = operates;
	}

	public static List<WorkflowObject> buildWfObjects(Workflow wf, Long[] ids) {
		List<WorkflowObject> rus = new ArrayList<WorkflowObject>();
		WorkflowObject wfo = null;
		for (Long id : ids) {
			wfo = new WorkflowObject();
			wfo.setWorkflow(wf);
			wfo.setObjectId(id);
			rus.add(wfo);
		}
		return rus;
	}
	
	/**
	 * 构建操作记录
	 * @param wf
	 * @param user
	 * @param msg
	 */
	public static void buildOperates(Workflow wf,User user,WorkflowOperateType type,String msg){
		List<WorkflowOperate> list=wf.getOperates();
		if(list==null)
				list=new ArrayList<WorkflowOperate>();
		list.add(new WorkflowOperate(wf,user,type,msg));
		wf.setOperates(list);
		
	}
	/**begin properties column constan**/
	public static final String UPDATED_AT = "updatedAt";
	public static final String CREATED_AT = "createdAt";
	public static final String SPONSOR = "sponsor";
	public static final String STATE = "state";
	/**end properties column constan**/

}
